#-*- coding:UTF-8 -*-

import mmap,os,md5,struct
import dictzip
from stat import ST_MTIME
import codecs

import httplib, mimetypes
import MySQLdb
import sys 
import time
import urllib2
import pickle

def encode_multipart_formdata(fields, files):
    """
    fields is a sequence of (name, value) elements for regular form fields.
    files is a sequence of (name, filename, value) elements for data to be uploaded as files
    Return (content_type, body) ready for httplib.HTTP instance
    """
    BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
    CRLF = '\r\n'
    L = []
    for (key, value) in fields:
        L.append('--' + BOUNDARY)
        L.append('Content-Disposition: form-data; name="%s"' % key)
        L.append('')
        L.append(value)
    for (key, filename, value) in files:
        L.append('--' + BOUNDARY)
        L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
        L.append('Content-Type: %s' % get_content_type(filename))
        L.append('')
        L.append(value)
    L.append('--' + BOUNDARY + '--')
    L.append('')
    body = CRLF.join(L)
    content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
    return content_type, body

def get_content_type(filename):
    return 'application/octet-stream'
    return mimetypes.guess_type(filename)[0] or 'application/octet-stream'



def post_multipart(host, selector, fields, files):
    """
    Post fields and files to an http host as multipart/form-data.
    fields is a sequence of (name, value) elements for regular form fields.
    files is a sequence of (name, filename, value) elements for data to be uploaded as files
    Return the server's response page.
    """
    content_type, body = encode_multipart_formdata(fields, files)
    h = httplib.HTTPConnection(host)
    h.putrequest('POST', selector)
    h.putheader('content-type', content_type)
    h.putheader('content-length', str(len(body)))
    h.endheaders()
    h.send(body)
    resp=h.getresponse()
    return resp

class StarDict(object):
    def __init__(self,dictname):
        self.name=dictname
        self.data = None
        self.inx=None
        self.wordlist=[]
        self.initialize(dictname)
    
    def initialize(self,name):
        #self.data=open(name+".dict","rb")
        self.data=dictzip.DictzipFile(name+".dict.dz")
        self.inx=open(name+".idx",'rb').read()
        self.info=open(name+".ifo",'rb').read()
        runner=0
        self.wordlist.append(runner)
        i=0
        while True:
            runner = self.inx.find('\0',runner)
            if runner == -1:
                break
            runner+=9
            self.wordlist.append(runner)
            i+=1
    def get_word(self,index):
        "get word from self.index"
        left_b = self.wordlist[index]
        right_b = self.wordlist[index+1] - 9
        #print self.index[left_b:right_b]
        return self.inx[left_b:right_b]
    def get_explanation(self,index):
        "get word from self.index"
        right_b = self.wordlist[index+1] - 9
        offset_v = 0
        size_v =  0
        offset = self.inx[right_b+1:right_b+5]
        size = self.inx[right_b+5:right_b+9]
        offset_v = struct.unpack('!i',offset)[0]
        size_v = struct.unpack('!i',size)[0]

        self.data.seek(offset_v)
        return self.data.read(size_v)
    
    def __del__(self):
        if self.data:
            self.data.close() 
        


def test():
    dictname=r"C:\Documents and Settings\Linxh\My Documents\stardict\stardict-21shijishuangxiangcidian-2.4.2\21shijishuangxiangcidian"
    sd=StarDict(dictname)
    out=open(dictname+".dict","wb")
    index=len(sd.wordlist)-2
    right_b = sd.wordlist[index+1] - 9
    offset = sd.inx[right_b+1:right_b+5]
    size = sd.inx[right_b+5:right_b+9]
    offset_v = struct.unpack('!i',offset)[0]
    offset_v = struct.unpack('!i',offset)[0]
    size_v = struct.unpack('!i',size)[0]
    size=offset_v+size_v
    sd.data.extract(out,size)
    out.close()
    for index in range(len(sd.wordlist)-1):
        right_b = sd.wordlist[index+1] - 9
        offset = sd.inx[right_b+1:right_b+5]
        size = sd.inx[right_b+5:right_b+9]
        offset_v = struct.unpack('!i',offset)[0]
        size_v = struct.unpack('!i',size)[0]
        print offset_v,size_v
        
import urllib
import urllib2

def newDict():
    data={
          "dictid":8,
          "name":"朗道汉英字典5.0",
          "version":"2.4.2",
          "wordcount":"405719"
          }
    data=urllib.urlencode(data)
    url="http://pyutility.appspot.com/dict/newdict"
    resp=urllib2.urlopen(url, data)
    print resp.read()

def uploadDict(dictname=r"C:\Documents and Settings\Linxh\My Documents\stardict\stardict-langdao-ce-gb-2.4.2\langdao-ce-gb"):
    sd=StarDict(dictname)
    dictsize=len(sd.wordlist)
    index=0
    depart=0
    while index<dictsize-1:
        depart+=1    
        words=[]
        startword=""
        datasize=0
        right_b=sd.wordlist[index+1] - 9
        indexsize=right_b
        offset=sd.inx[right_b+1:right_b+5]
        size=sd.inx[right_b+5:right_b+9]
        offset_v=struct.unpack('!i',offset)[0]
        size_v=struct.unpack('!i',size)[0]
        startoff=offset_v
        datasize+=size_v
        startword=sd.get_word(index)
        words.append((sd.get_word(index),offset_v,size_v))
        index+=1
        while index<dictsize-1:
            right_b=sd.wordlist[index+1] - 9
            offset=sd.inx[right_b+1:right_b+5]
            size=sd.inx[right_b+5:right_b+9]
            offset_v=struct.unpack('!i',offset)[0]
            size_v=struct.unpack('!i',size)[0]
            words.append((sd.get_word(index),offset_v,size_v))
            if datasize+size_v>1000000 or right_b-indexsize>512000:
                break
            else:
                datasize+=size_v
                index+=1
        print startoff,datasize
        host="127.0.0.1:8080"
        host="pyutility.appspot.com"
        #upload index
        dictionid=8
        para=[]
        para.append(("dictid",str(dictionid)))
        para.append(("startword",startword))
        para.append(("departid",str(depart)))
        files=[]
        files.append(("data","tmp",pickle.dumps(words,2)))
        resp=post_multipart(host,"/dict/uploadindex",para,files)
        print resp.read()
        #upload data
        para=[]
        files=[]
        para.append(("dictid",str(dictionid)))
        para.append(("startoffset",str(startoff)))
        para.append(("departid",str(depart)))
        sd.data.seek(startoff)
        data=sd.data.read(datasize)
        files.append(("data","tmp",data))
        resp=post_multipart(host,"/dict/uploaddata",para,files)
        print resp.read()
        
if __name__=="__main__":
    #test()
    uploadDict()
    newDict()